package cn.ac.ict.fpevaluation.utils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import com.google.gson.Gson;
import cn.ac.ict.fpevaluation.bean.AtomTrajectoryBean;
import cn.ac.ict.fpevaluation.bean.FusionBean;
import cn.ac.ict.fpevaluation.constant.Constant;

public class DataOperationToDiskUtils {
    private static Gson gson = new Gson();


    public static List<AtomTrajectoryBean> getTrainingData() {
        return getTrajData(Constant.TRAINING_PATH);
    }

    /**
     * 读取原始数据
     *
     * @return
     */
    public static List<AtomTrajectoryBean> getOriginalData() {
        return getTrajData(Constant.STORE_PATH);
    }

    public static List<List<AtomTrajectoryBean>> getClusters() {
        List<String> fileList = FileUtils.listSubDir(Constant.CLUSTER_RESULT);
        List<List<AtomTrajectoryBean>> res = new ArrayList<>();
        fileList.forEach(item -> {
            res.add(getTrajData(item));
        });

        return res;
    }


    public static List<AtomTrajectoryBean> getTrajData(String path) {
        /**
         * 保存读取到的数据
         */
        List<AtomTrajectoryBean> data = new ArrayList<AtomTrajectoryBean>();
        /**
         * 文件路径下的所有文件
         */
        List<String> fileList = FileUtils.getFileList(path);
       //System.out.println("读取存储路径:" + path + "--" + "共读取到" + fileList.size() + "个文件");

        /**
         * 读文件
         */
        BufferedReader br = null;
        try {
            for (int i = 0; i < fileList.size(); i++) {
                File f = new File(fileList.get(i));
                // 如果是文件夹直接退出
                if (f.isDirectory() || f.isHidden())
                    continue;

                br = new BufferedReader(new InputStreamReader(
                        new FileInputStream(f)));
                StringBuilder sb = new StringBuilder();
                String line = null;

                while ((line = br.readLine()) != null)
                    sb.append(line);

                data.add(gson.fromJson(sb.toString(), AtomTrajectoryBean.class));

                br.close();
            }
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return data;
    }


    /**
     * 将聚类结果写到硬盘
     *
     * @param data
     * @return
     */
    public static boolean writeClusterResultToDisk(List<List<AtomTrajectoryBean>> data, String clusterPath) {
        if (clusterPath == null)
            return false;

        File dirFile = new File(clusterPath);
        if (dirFile != null) {
            dirFile.mkdirs();
            dirFile.setReadable(true);
            dirFile.setWritable(true);
            dirFile.setExecutable(true);
        }


        boolean res = FileUtils.delAllFile(clusterPath);

        for (int i = 0; i < data.size(); i++) {
            String subDirPath = clusterPath + File.separator + (i + 1);
            dirFile = new File(subDirPath);
            if (dirFile != null) {
                dirFile.mkdirs();
                dirFile.setReadable(true);
                dirFile.setWritable(true);
                dirFile.setExecutable(true);
            }

            PrintWriter pw = null;

            List<AtomTrajectoryBean> clusters = data.get(i);
            for (int j = 0; j < clusters.size(); j++) {
                try {
                    // 文件名
                    String filePath = subDirPath + File.separator
                            + clusters.get(j).getName();

                    File atomicFile = new File(filePath);
                    atomicFile.createNewFile();

                    pw = new PrintWriter(atomicFile);
                    pw.write(gson.toJson(clusters.get(j),
                            AtomTrajectoryBean.class));

                    pw.flush();
                    pw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return true;
    }

    /**
     * 将聚类结果读入内存
     *
     * @return
     * @throws IOException
     */
    public static List<List<AtomTrajectoryBean>> readClusterResult() {
        String clusterPath = Constant.CLUSTER_RESULT;
        if (clusterPath == null)
            return null;

        /**
         * 创建路径文件
         */
        File dirFile = new File(clusterPath);
        /**
         * 存储结果
         */
        List<List<AtomTrajectoryBean>> result = new ArrayList<List<AtomTrajectoryBean>>();
        /**
         * 列出该路径下的所有文件(应该全是文件夹)
         */
        File[] clusterList = dirFile.listFiles();

        for (int i = 0; i < clusterList.length; i++) {
            /**
             * 存储某一类的所有原子轨迹
             */
            ArrayList<AtomTrajectoryBean> cluster = new ArrayList<AtomTrajectoryBean>();
            /**
             * 某一类的文件
             */
            File clusterDir = clusterList[i];
            if (clusterDir == null || !clusterDir.isDirectory()) {
                continue;
            }
            /**
             * 列出某一类下的所有文件
             */
            File[] atomicFiles = clusterDir.listFiles();

            try {
                BufferedReader br = null;
                for (int j = 0; j < atomicFiles.length; j++) {
                    // 磁盘操作
                    br = new BufferedReader(new InputStreamReader(new FileInputStream(atomicFiles[j])));
                    String line = null;
                    StringBuilder sb = new StringBuilder();
                    while ((line = br.readLine()) != null) {
                        sb.append(line);
                    }

                    cluster.add(gson.fromJson(sb.toString(), AtomTrajectoryBean.class));

                    br.close();
                }
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            result.add(cluster);
        }

        return result;
    }

    /**
     * 将融合结果读入内存
     *
     * @return
     */
    public static List<FusionBean> readFusionResult() {
        List<FusionBean> res = new ArrayList<FusionBean>();
        /**
         * 融合结果存储路径
         */
        String fusionResultPath = Constant.FUSION_RESULT;
        File f = new File(fusionResultPath);
        /**
         * 列出文件夹下的所有文件
         */
        File[] files = f.listFiles();
        /**
         * 读取文件
         */
        BufferedReader br = null;
        try {
            for (File file : files) {
                if (file.isDirectory() || file.isHidden()) continue;

                br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));

                String line = null;
                StringBuilder sb = new StringBuilder();
                while ((line = br.readLine()) != null) sb.append(line);

                res.add(gson.fromJson(sb.toString(), FusionBean.class));

                br.close();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return res;
    }

    /**
     * 将融合结果写入磁盘
     *
     * @param data
     * @return
     */
    public static boolean writeFusionResultToDisk(List<FusionBean> data) {
        String fusionResultPath = Constant.FUSION_RESULT;
        PrintWriter pw = null;
        String name = null;
        try {
            for (FusionBean fusionBean : data) {
                fusionBean.setName(name = (GetDateUtils.getDate() + "-" + UUID.randomUUID() + ".txt"));
                FileUtils.delAllFile(fusionResultPath);
                pw = new PrintWriter(new FileOutputStream(fusionResultPath + File.separator + name));

                pw.write(gson.toJson(fusionBean));
                pw.flush();
                pw.close();
            }

        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return true;
    }
}
